﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Reflection;
using System.Data.Common;

namespace Petaframe.DataAccess
{
    /// <summary>
    /// Verilen sınıfa ait property ve varsa attribute değerlerinin okunması için kullanılır.
    /// </summary>
   internal  class ClassDecomposer
    {

       public TableInfo ForType(Type tip, IParameterBuilder parameterBuilder, IEscapeSqlIdentifier escapeSqlIdentifier, DbProviderFactory factory)
       {
           TableInfo ti = new TableInfo();

           var tableNameAttributeArray = tip.GetCustomAttributes(typeof(TableNameAttribute), false);
           if (tableNameAttributeArray.Length == 0)
               throw new NullReferenceException("Tablo adı okunamıyor.Kullanılan sınıfların başında [TableName] attribute olmak zorundadır.");

           ti.TableName = escapeSqlIdentifier.EscapeSqlIdentifier((tableNameAttributeArray[0] as TableNameAttribute).TableName);
           ti.ClassName = tip.Name;
           var properties = tip.GetProperties(BindingFlags.Instance | BindingFlags.Public);

           int index = 0;

           foreach (var item in properties)
           {
               CustomPropertyInfo cpi = new CustomPropertyInfo();
               cpi.CurrentPropertyDetails = item;
               cpi.PropertyName = item.Name;
               cpi.PropertyType = item.PropertyType;
               cpi.ParameterInfo = parameterBuilder.CreateParameter(factory,index, item);

               var primaryKeyPropertyList = item.GetCustomAttributes(typeof(TablePrimaryKeyAttribute), false);
               if (primaryKeyPropertyList.Length > 0)
               {
                   ti.HasPrimaryKey = true;
                   cpi.PrimaryKey = true;
                   cpi.AutoIncrement = (primaryKeyPropertyList[0] as TablePrimaryKeyAttribute).AutoIncrement;
                   ti.PrimaryKeys.Add(cpi);
               }

               ti.Properties.Add(cpi);
               // ti.Parameters.Add(item.Name,pInfo);
               index++;
           }

           ti.TableSqlCommands = new TableQueries(ti);

           return ti;

          
       }

       public TableInfo ForEntity<T>(T obj, IParameterBuilder parameterBuilder, IEscapeSqlIdentifier escapeSqlIdentifier, DbProviderFactory factory)
       {
           TableInfo ti = new TableInfo();

           Type tip = obj.GetType();          

           var tableNameAttributeArray = tip.GetCustomAttributes(typeof(TableNameAttribute), false);
           if (tableNameAttributeArray.Length==0)
               throw new NullReferenceException("Tablo adı okunamıyor.Kullanılan sınıfların başında [TableName] attribute olmak zorundadır.");

           ti.TableName = escapeSqlIdentifier.EscapeSqlIdentifier((tableNameAttributeArray[0] as TableNameAttribute).TableName);
           ti.ClassName = tip.Name;          

           var properties = tip.GetProperties(BindingFlags.Instance | BindingFlags.Public);

           int index = 0;

           foreach (var item in properties)
           {
               CustomPropertyInfo cpi = new CustomPropertyInfo();
               cpi.CurrentPropertyDetails = item;
               cpi.PropertyName = item.Name;
               cpi.PropertyType = item.PropertyType;
               cpi.ParameterInfo = parameterBuilder.CreateParameter(factory,index, item);

               var primaryKeyPropertyList = item.GetCustomAttributes(typeof(TablePrimaryKeyAttribute), false);
               if (primaryKeyPropertyList.Length > 0)
               {
                   ti.HasPrimaryKey = true;
                   cpi.PrimaryKey = true;
                   cpi.AutoIncrement = (primaryKeyPropertyList[0] as TablePrimaryKeyAttribute).AutoIncrement;                  
                   ti.PrimaryKeys.Add(cpi);
               }

               ti.Properties.Add(cpi);
               //ti.Parameters.Add(item.Name, pInfo);
               index++;
           }

           ti.TableSqlCommands = new TableQueries(ti);
           return ti;
       }


       public TableInfo ForObject(object obj, IParameterBuilder parameterBuilder, IEscapeSqlIdentifier escapeSqlIdentifier, DbProviderFactory factory)
       {
           return ForType(obj.GetType(), parameterBuilder, escapeSqlIdentifier,factory);
       }

      

    }
}
